package com.t.codebook.controller;
import com.github.pagehelper.PageInfo;
import com.t.codebook.annotation.AuthCheck;
import com.t.codebook.common.BaseResponse;
import com.t.codebook.common.DeleteRequest;
import com.t.codebook.common.ErrorCode;
import com.t.codebook.common.ResultUtils;
import com.t.codebook.constant.UserConstant;
import com.t.codebook.exception.BusinessException;
import com.t.codebook.exception.ThrowUtils;
import com.t.codebook.model.dto.codeBank.CodeBankAddRequest;
import com.t.codebook.model.dto.codeBank.CodeBankEditRequest;
import com.t.codebook.model.dto.codeBank.CodeBankQueryRequest;
import com.t.codebook.model.dto.codeBank.CodeBankUpdateRequest;
import com.t.codebook.model.entity.CodeBank;
import com.t.codebook.model.entity.User;
import com.t.codebook.model.vo.CodeBankVO;
import com.t.codebook.service.CodeBankService;
import com.t.codebook.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

/**
* 代码库控制层
*
*/
@RestController
@RequestMapping("/codeBank")
@Slf4j
public class CodeBankController {

@Resource
private CodeBankService codeBankService;

    @Resource
    private UserService userService;


        /**
        * 创建代码库
        *
        * @param codeBankAddRequest
        * @param request
        * @return
        */
        @PostMapping("/add")
        public BaseResponse<Long> addCodeBank(@Valid @RequestBody CodeBankAddRequest codeBankAddRequest, HttpServletRequest request) {
            ThrowUtils.throwIf(codeBankAddRequest == null, ErrorCode.PARAMS_ERROR);
            // 在此处将实体类和 DTO 进行转换
            CodeBank codeBank = new CodeBank();
            BeanUtils.copyProperties(codeBankAddRequest, codeBank);
            // 写入数据库
            boolean result = codeBankService.save(codeBank);
            ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
            // 返回新写入的数据 id
            long newCodeBankId = codeBank.getId();
            return ResultUtils.success(newCodeBankId);
            }

        /**
        * 删除代码库
        *
        * @param deleteRequest
        * @param request
        * @return
        */
        @PostMapping("/delete")
        public BaseResponse<Boolean> deleteCodeBank(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
            if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            User user = userService.getLoginUser(request);
            long id = deleteRequest.getId();
            // 判断是否存在
            CodeBank oldCodeBank = codeBankService.getById(id);
            ThrowUtils.throwIf(oldCodeBank == null, ErrorCode.NOT_FOUND_ERROR);
            // 仅本人或管理员可删除
            if (!oldCodeBank.getUserId().equals(user.getId()) && !userService.isAdmin(request)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
            }
            // 操作数据库
            boolean result = codeBankService.removeById(id);
            ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
            return ResultUtils.success(true);
            }

        /**
        * 更新代码库（仅管理员可用）
        *
        * @param codeBankUpdateRequest
        * @return
        */
        @PostMapping("/update")
        @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
        public BaseResponse<Boolean> updateCodeBank(@Valid @RequestBody CodeBankUpdateRequest codeBankUpdateRequest) {
            if (codeBankUpdateRequest == null || codeBankUpdateRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            // 判断是否存在
            long id = codeBankUpdateRequest.getId();
            CodeBank oldCodeBank = codeBankService.getById(id);
            ThrowUtils.throwIf(oldCodeBank == null, ErrorCode.NOT_FOUND_ERROR);
            // 操作数据库
            boolean result = codeBankService.updateById(oldCodeBank);
            ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
            return ResultUtils.success(true);
            }


        /**
        * 根据 id 获取代码库（封装类）
        *
        * @param id
        * @return
        */
        @GetMapping("/get/vo")
        public BaseResponse<CodeBankVO> getCodeBankById(long id) {
                ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
                // 查询数据库
                CodeBank codeBank = codeBankService.getById(id);
                ThrowUtils.throwIf(codeBank == null, ErrorCode.NOT_FOUND_ERROR);
                // 获取封装类
                return ResultUtils.success(codeBankService.getCodeBankVO(id));
            }


        /**
        * 分页获取代码库列表（封装类）
        *
        * @param codeBankQueryRequest
        * @param request
        * @return
        */
        @PostMapping("/list/page/vo")
        public BaseResponse<PageInfo<CodeBankVO>> listCodeBankVOByPage(@RequestBody CodeBankQueryRequest codeBankQueryRequest,HttpServletRequest request) {
               // 补充查询条件，只查询当前登录用户的数据
               User loginUser = userService.getLoginUser(request);
               long size = codeBankQueryRequest.getPageSize();
               codeBankQueryRequest.setUserId(loginUser.getId());
               // 限制爬虫
               ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
               // 查询数据库
               PageInfo<CodeBankVO> codeBankPage = codeBankService.getCodeVOPage(codeBankQueryRequest);
               // 获取封装类
               return ResultUtils.success(codeBankPage);
            }


        /**
        * 编辑代码库（给用户使用）
        *
        * @param codeBankEditRequest
        * @param request
        * @return
        */
        @PostMapping("/edit")
        public BaseResponse<Boolean> editCodeBank(@Valid @RequestBody CodeBankEditRequest codeBankEditRequest, HttpServletRequest request) {
               if (codeBankEditRequest == null || codeBankEditRequest.getId() <= 0) {
                  throw new BusinessException(ErrorCode.PARAMS_ERROR);
               }
               // 在此处将实体类和 DTO 进行转换
               CodeBank codeBank = new CodeBank();
               BeanUtils.copyProperties(codeBankEditRequest, codeBank);
               User loginUser = userService.getLoginUser(request);
               // 判断是否存在
               long id = codeBankEditRequest.getId();
               CodeBank oldCodeBank = codeBankService.getById(id);
               ThrowUtils.throwIf(oldCodeBank == null, ErrorCode.NOT_FOUND_ERROR);
               // 仅本人或管理员可编辑
               if (!oldCodeBank.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
                  throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
               }
               // 操作数据库
               boolean result = codeBankService.updateById(codeBank);
               ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
               return ResultUtils.success(true);
           }


}
